﻿using System;
using System.Collections.Generic;
using System.Net;

namespace Hourglass.Qrobot.Http
{
    public class DefaultRetryManager : IRetryManager
    {
        private readonly Dictionary<HttpStatusCode, RetryConfig> _retryConfigs;
        private int _counter = 0;

        public DefaultRetryManager()
        {
            this._retryConfigs = new Dictionary<HttpStatusCode, RetryConfig>();
            DefaultInit();
        }

        public virtual bool ExceptionRetry(HttpRequestHandler handler, WebRequest request, Exception e)
        {
            var webException = e as WebException;
            var httpResponse = webException?.Response as HttpWebResponse;
            if (httpResponse != null && this._retryConfigs.ContainsKey(httpResponse.StatusCode))
            {
                var config = this._retryConfigs[httpResponse.StatusCode];
                return config.Times > ++config.Counter;
            }
            return 3 > ++_counter;
        }

        public void Reset()
        {
            this._counter = 0;
        }

        private void DefaultInit()
        {
            this._retryConfigs.Add(HttpStatusCode.BadGateway, new RetryConfig(200, 5));
            this._retryConfigs.Add(HttpStatusCode.NotFound, new RetryConfig(700, 2));
        }

        public sealed class RetryConfig
        {
            /// <summary>
            /// 失败后睡眠毫秒数
            /// </summary>
            public int SleepMillisecond { get; set; }

            /// <summary>
            /// 尝试次数
            /// </summary>
            public int Times { get; set; }

            /// <summary>
            /// 已发生次数
            /// </summary>
            public int Counter { get; set; }

            public RetryConfig() { }

            public RetryConfig(int sleepMillisecond, int times)
            {
                this.SleepMillisecond = sleepMillisecond;
                this.Times = times;
            }

            public static RetryConfig Normal => new RetryConfig(200, 3);
        }
    }
}
